import wx
import NotifyEvent


IMAGE_PADDING = 0
SCROLLBAR_SIZE = 15
THRESHOLD_LINE_LENGTH = 105


class ViewPanel(wx.Panel):
	def __init__(self, parent, ID):
		wx.Panel.__init__(self, parent, ID)
		self.__active_id = 0
		self.__last_active_id = -1

		self.__views = []
		for x in range(4):
			view = ImagePanel(self, wx.ID_ANY, str(x))
			self.__views.append(view)

		self.sizer_full = wx.GridSizer(rows=1, cols=1, hgap=0, vgap=0)
		self.sizer_full.Add(self.__views[self.__active_id], 0, wx.EXPAND)
		self.sizer_split = wx.GridSizer(rows=2, cols=2, hgap=0, vgap=0)
		for view in self.__views:
			self.sizer_split.Add(view, 1, wx.EXPAND)

		self.SetActiveView(0)
		self.__ShowInactive()

		#self.Bind(wx.EVT_RIGHT_UP, self.__ToggleShow)

	def SetImage(self, name, image, id=None):
		if not id:
			id = self.__active_id
		self.__views[id].SetImage(name, image)
		self.__UpdateStatusBar()

	def ClearImage(self):
		for view in self.__views:
			if view.GetName() is self.GetImageName():
				view.SetImage(None, None)

	def GetImageName(self):
		return self.__views[self.__active_id].GetName()

	def GetPreviousImageName(self):
		if self.__last_active_id >= 0:
			return self.__views[self.__last_active_id].GetName()
		else:
			return None

	def GetViewByName(self, name):
		for view in self.__views:
			if view.GetName() == name:
				return view

	def ToggleShow(self):
		if self.flag_fullscreen == False:
			self.__HideInactive()
		else:
			self.__ShowInactive()
		self.Refresh()
		self.Layout()

	def SetActiveView(self, id):
		self.__views[self.__active_id].SetActive(False)
		self.sizer_full.Remove(self.__views[self.__active_id])
		self.__last_active_id = self.__active_id
		self.__active_id = id
		self.sizer_full.Add(self.__views[self.__active_id], 0, wx.EXPAND)
		self.__views[self.__active_id].SetActive(True)
		self.Refresh()

		self.__UpdateStatusBar()

	def __UpdateStatusBar(self):
		self.GetParent().statusbar.SetStatusText("Buffer: %s" % self.GetImageName(), 2)

	def __HideInactive(self):
		self.flag_fullscreen = True
		for view in self.__views:
			if not view.is_active:
				view.Hide()
		self.SetSizer(self.sizer_full, False)

	def __ShowInactive(self):
		self.flag_fullscreen = False
		for view in self.__views:
			if not view.is_active:
				view.Show()
		self.SetSizer(self.sizer_split, False)


class ImagePanel(wx.Panel):
	def __init__(self, parent, ID, viewname):
		wx.Panel.__init__(self, parent, ID, name=viewname)
		self.SetBackgroundColour(wx.BLACK)
		self.Refresh(True)

		self.__id = viewname
		self.__name = ""
		self.__image = None
		self.__bitmap = None
		self.__pad_x = 0
		self.__pad_y = 0
		self.__bitmap_w = 0
		self.__bitmap_h = 0
		self.is_active = False

		self.Bind(wx.EVT_PAINT, self.__OnPaint)
		self.Bind(wx.EVT_MOTION, self.__OnMotion)
		self.Bind(wx.EVT_LEFT_DOWN, self.__OnLeftDown)
		self.Bind(wx.EVT_RIGHT_UP, self.__ToggleShow)

	def SetImage(self, name, image):
		self.__name = name
		self.__image = image
		self.__SetBitmap(self.__image)
		self.Refresh()
	
	def GetName(self):
		return self.__name

	def SetActive(self, flag):
		self.is_active = flag
	
	def notify(self, t):
		self.__threshold_limit = t
		self.Refresh()

	def __OnNotify(self, event):
		self.__threshold_limit = event.threshold
		self.Refresh()

	def __OnLeftDown(self, event):
		if not self.is_active:
			self.GetParent().SetActiveView(int(self.__id))
	
	def __ToggleShow(self, event):
		self.GetParent().ToggleShow()

	def __OnMotion(self, event):
		original_pos = event.GetPositionTuple()

		colour = self.dc.GetPixel(*original_pos)
		rgb = (colour.Red(), colour.Green(), colour.Blue()) 
		self.GetParent().GetParent().statusbar.SetStatusText("RGB: %u %u %u" % rgb, 1)

		pos = (original_pos[0] - self.__pad_x, original_pos[1] - self.__pad_y)
		if 0 <= pos[0] <= self.__bitmap_w and 0 <= pos[1] <= self.__bitmap_h:
			self.GetParent().GetParent().statusbar.SetStatusText("Pos: %u %u" % pos, 0)

		# see if need to draw scroll bar bellow histogram
		try:
			self.__paint_scrollbar
		except AttributeError:
			pass
		else:
			if self.__scrollbar_x <= original_pos[0] <= self.__scrollbar_x+SCROLLBAR_SIZE and \
					self.__scrollbar_y <= original_pos[1] <= self.__scrollbar_y+SCROLLBAR_SIZE and \
					self.__pad_x <= original_pos[0] <= self.__pad_x+self.__bitmap_w - 1:

				if not self.__paint_scrollbar:
					self.__change_paint_scrollbar()

				if event.m_leftDown:
					self.__scrollbar_x = original_pos[0]-SCROLLBAR_SIZE/2
					threshold = (original_pos[0]-self.__pad_x)/2
					self.Refresh()
					display_id = (int(self.__id)+2) % 4
					self.GetParent().GetParent().threshold_control(self.__name, threshold, display_id)

			else:

				if self.__paint_scrollbar:
					self.__change_paint_scrollbar()

	def __change_paint_scrollbar(self):
			self.__paint_scrollbar = not self.__paint_scrollbar
			self.Refresh()

	def __OnPaint(self, event):
		self.dc = wx.PaintDC(self)

		brush = wx.Brush(wx.BLACK)
		self.dc.SetBackground(brush)
		self.dc.Clear()
		self.dc.SetBrush(wx.TRANSPARENT_BRUSH)
		dw, dh = self.dc.GetSize()
		if self.__bitmap:
			pad_x = (dw - self.__bitmap_w)/2
			pad_y = (dh - self.__bitmap_h)/2

			if pad_x < IMAGE_PADDING:
				pad_x = IMAGE_PADDING
			if pad_y < IMAGE_PADDING:
				pad_y = IMAGE_PADDING

			self.dc.DrawBitmap(self.__bitmap, pad_x, pad_y)
			self.__pad_x = pad_x
			self.__pad_y = pad_y

			# draw scrollbar
			try:
				self.__paint_scrollbar
			except AttributeError:
				pass
			else:
				if self.__scrollbar_x <= 0:
					self.__scrollbar_x = self.__pad_x - SCROLLBAR_SIZE/2
				self.__scrollbar_y = self.__pad_y + self.__bitmap_h+5

				if self.__paint_scrollbar:
					self.dc.SetPen(wx.Pen("#999999", 1))
				else:
					self.dc.SetPen(wx.Pen("#222222", 1))
				self.dc.DrawRectangle(self.__scrollbar_x, self.__scrollbar_y, \
							SCROLLBAR_SIZE, SCROLLBAR_SIZE)
				self.dc.DrawLine(self.__scrollbar_x + SCROLLBAR_SIZE/2, \
								self.__scrollbar_y, \
								self.__scrollbar_x + SCROLLBAR_SIZE/2, \
								self.__scrollbar_y - THRESHOLD_LINE_LENGTH
								)
				self.dc.SetPen(wx.Pen("#006600", 3))
				try:
					self.__threshold_limit
				except AttributeError:
					pass
				else:
					self.dc.DrawLine(self.__pad_x, self.__scrollbar_y-5, self.__pad_x+self.__threshold_limit*2, self.__scrollbar_y-5)

		# draw outline
		if self.is_active:
			self.dc.SetPen(wx.Pen("light green", 1))
		else:
			self.dc.SetPen(wx.Pen("#222222", 1))
		self.dc.DrawRectangle(0, 0, dw, dh)

	def __SetBitmap(self, image):
		if image:
			self.__bitmap = image.ConvertToBitmap()
			self.__bitmap_w = self.__bitmap.GetWidth()
			self.__bitmap_h = self.__bitmap.GetHeight()
			if self.__name.endswith(' - histogram'):
				self.__paint_scrollbar = False
				self.__scrollbar_x = 0
				self.Bind(NotifyEvent.EVT_NOTIFY, self.__OnNotify)
		else:
			self.__bitmap = None
